{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "import math\n",
    "import numpy as np\n",
    "import numpy.linalg as npl\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 5.1,2 Linear Independence, Basis"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(array([ 1.,  2., -3.]), [1, 2, -3])"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#Cash Flows Ex\n",
    "r = .05 #interest\n",
    "e1 = np.array([1,0,0]) #initial payment\n",
    "l1 = np.array([1,-(1+r),0]) #first loan: t0: $1, t1: paid back with interest\n",
    "l2 = np.array([0,1,-(1+r)]) #second loan: t1: $1, t2: paid back with interest\n",
    "c = [1,2,-3] #cash flow\n",
    "#Expansion coefficients:\n",
    "alpha3 = -c[2]/(1+r)\n",
    "alpha2 = -c[1]/(1+r) - c[2]/(1+r)**2\n",
    "alpha1 = c[0] + c[1]/(1+r) + c[2]/(1+r)**2 #NPV\n",
    "alpha1*e1 + alpha2 * l1 + alpha3*l2, c"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 5.3 Orthonormal Vectors"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1.0, 0.9999999999999999, 0.9999999999999999, 0.0, 0.0, 0.0)"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a1,a2,a3 = np.array([0,0,-1]),np.array([1,1,0])/math.sqrt(2), np.array([1,-1,0])/math.sqrt(2)\n",
    "npl.norm(a1),npl.norm(a2),npl.norm(a3), np.inner(a1,a2),np.inner(a1,a2),np.inner(a2,a3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(array([1., 2., 3.]), [1, 2, 3])"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = [1,2,3]\n",
    "beta1,beta2,beta3 = np.inner(a1,x),np.inner(a2,x),np.inner(a3,x)\n",
    "xexp = beta1*a1 + beta2*a2 + beta3*a3\n",
    "xexp, x #expansion of x in basis unchanged "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 5.4 Gram-Schmidt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 79,
   "metadata": {},
   "outputs": [],
   "source": [
    "def gram_schmidt(a, tol=1e-10):\n",
    "    q = []\n",
    "    for i in range(len(a)):\n",
    "        qtilde = a[i]\n",
    "        for j in range(i):\n",
    "            qtilde = qtilde - np.inner(q[j],a[i])*q[j]\n",
    "        if npl.norm(qtilde) < tol:\n",
    "            print(\"Vectors linearly dependent\")\n",
    "        q.append(qtilde/npl.norm(qtilde))\n",
    "    return q\n",
    "\n",
    "\n",
    "a = np.array([[-1,1,-1,1],[-1,3,-1,3],[1,3,5,7]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 82,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "([array([-0.5,  0.5, -0.5,  0.5]),\n",
       "  array([0.5, 0.5, 0.5, 0.5]),\n",
       "  array([-0.5, -0.5,  0.5,  0.5])],\n",
       " 1.0,\n",
       " 0.0,\n",
       " 0.0,\n",
       " 1.0,\n",
       " 0.0,\n",
       " 1.0)"
      ]
     },
     "execution_count": 82,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "q = gram_schmidt(a)\n",
    "q, npl.norm(q[0]), np.inner(q[0],q[1]),np.inner(q[0],q[2]),npl.norm(q[2]), np.inner(q[1],q[2]), npl.norm(q[2])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Vectors linearly dependent\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "([array([-1,  1, -1,  1]),\n",
       "  array([-1,  3, -1,  3]),\n",
       "  array([-1.8,  2.8, -1.8,  2.8])],\n",
       " [array([-0.5,  0.5, -0.5,  0.5]),\n",
       "  array([0.5, 0.5, 0.5, 0.5]),\n",
       "  array([-0.5,  0.5, -0.5,  0.5])])"
      ]
     },
     "execution_count": 86,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#Linear dependence via linear combination of a0 and a1\n",
    "b = [a[0],a[1],1.3*a[0] + .5*a[1]]\n",
    "b, gram_schmidt(b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 89,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Vectors linearly dependent\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[array([0.70710678, 0.70710678]),\n",
       " array([-0.70710678,  0.70710678]),\n",
       " array([-0.9486833 , -0.31622777])]"
      ]
     },
     "execution_count": 89,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#Linear dependence via linear combination of three 2-vecs\n",
    "three_two_vecs = np.array([[1,1],[1,2],[-1,1]])\n",
    "gram_schmidt(three_two_vecs)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
